﻿using Newtonsoft.Json;
using System.Security.Cryptography;
using System.Text;

namespace Utils
{
    public class WXBizDataCrypt
    {
        private string _appId;
        private string _sessionKey;

        public WXBizDataCrypt(string appId, string sessionKey)
        {
            _appId = appId;
            _sessionKey = sessionKey;
        }

        /// <summary>
        /// 解密微信加密数据
        /// </summary>
        /// <param name="encryptedData">加密数据</param>
        /// <param name="iv">初始向量</param>
        /// <returns>解密后的明文</returns>
        public string Decrypt(string encryptedData, string iv)
        {
            // 1. 转换输入参数为字节数组
            var encryptedBytes = Convert.FromBase64String(encryptedData);
            var sessionKeyBytes = Convert.FromBase64String(_sessionKey);
            var ivBytes = Convert.FromBase64String(iv);

            try
            {
                // 2. 使用AES-128-CBC解密
                using (var aes = Aes.Create())
                {
                    aes.Key = sessionKeyBytes;
                    aes.IV = ivBytes;
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    using (var decryptor = aes.CreateDecryptor())
                    using (var ms = new System.IO.MemoryStream())
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                    {
                        // 直接写入解密数据到MemoryStream
                        cs.Write(encryptedBytes, 0, encryptedBytes.Length);
                        cs.FlushFinalBlock();

                        // 获取完整的解密字节数组
                        var decryptedBytes = ms.ToArray();

                        // 3. 转换为UTF-8字符串
                        var resultJson = Encoding.UTF8.GetString(decryptedBytes);

                        // 4. 验证并解析JSON
                        try
                        {
                            var jsonObj = JsonConvert.DeserializeObject<dynamic>(resultJson);

                            // 5. 验证AppId
                            if (jsonObj.watermark.appid.ToString() != _appId)
                            {
                                throw new Exception("解密后的数据验证失败：AppId不匹配");
                            }

                            return resultJson;
                        }
                        catch (JsonReaderException jsonEx)
                        {
                            // 处理不完整JSON的情况
                            Console.WriteLine($"JSON解析失败: {jsonEx.Message}");
                            Console.WriteLine($"原始解密字符串: {resultJson}");

                            // 尝试修复不完整的JSON（仅作为临时解决方案）
                            if (resultJson.Trim().EndsWith("}"))
                            {
                                return resultJson;
                            }
                            else
                            {
                                // 尝试添加缺失的右花括号（谨慎使用，可能掩盖其他问题）
                                var fixedJson = resultJson.Trim() + "}";
                                try
                                {
                                    var jsonObj = JsonConvert.DeserializeObject<dynamic>(fixedJson);
                                    return fixedJson;
                                }
                                catch
                                {
                                    throw new Exception("无法修复不完整的JSON数据", jsonEx);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("解密失败", ex);
            }
        }
    }
}
